﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using Legazpi.Payroll.DataAccess.Base;
using Legazpi.Payroll.DataAccess.Repositories;
using Legazpi.Payroll.DataAccess.DataObjects;
using Legazpi.Payroll.BusinessLogic.Services.Interfaces;
using System.Linq;

namespace Legazpi.Payroll.BusinessLogic.Services
{
    public class DayTimeRecordService : IDayTimeRecordService
    {
        #region Fields

        private DbContext _dbContext;
        private IDayTimeRecordRepository _dayTimeRecordRepository;
        private IPayrollSummaryService _payrollSummaryService;

        private IDatabaseFactory _dbFactory;
        #endregion

        #region ctor

        public DayTimeRecordService()
            : this(new DatabaseFactory())
        {

        }

        public DayTimeRecordService(IDatabaseFactory dbFactory)
        {
            if (dbFactory == null) throw new ArgumentNullException("dbFactory");
            _dbFactory = dbFactory;
            DbContext = dbFactory.Get();
        }

        private DbContext DbContext
        {
            get { return _dbContext; }
            set
            {
                _dbContext = value;
                _dayTimeRecordRepository = new DayTimeRecordRepository(_dbContext);
                _payrollSummaryService = new PayrollSummaryService(_dbFactory);
            }
        }

        #endregion

        public DayTimeRecord GetById(int id)
        {
            return _dayTimeRecordRepository.GetById(id);
        }

        public IEnumerable<DayTimeRecord> GetAll()
        {
            return _dayTimeRecordRepository.GetAll();
        }

        public IEnumerable<DayTimeRecord> Get()
        {
            throw new NotImplementedException();
        }

        public DayTimeRecord GetEmployeeDTRbyPayroll(Employee employee, PayrollDate payDate)
        {
            var dtr = _dayTimeRecordRepository.GetQuery()
                .Where(x => x.EmployeeId == employee.Id && x.PayrollDateId == payDate.Id)
                .Take(1)
                .FirstOrDefault();
            if (dtr != null)
                return dtr;
            else
                return new DayTimeRecord 
                { 
                    EmployeeId = employee.Id, 
                    Employee = employee, 
                    PayrollDateId = payDate.Id 
                };                
        }
        public DayTimeRecord GetEmployeeDTRbyPayroll(int employeeId, int payDateId)
        {
           return _dayTimeRecordRepository.Get(x => x.EmployeeId == employeeId && x.PayrollDateId == payDateId);           
        }

        public void Add(DayTimeRecord dayTimeRecord)
        {
            _dayTimeRecordRepository.Add(dayTimeRecord);
            ComputeSummary(dayTimeRecord);
        }

        public void Update(DayTimeRecord dayTimeRecord)
        {
            _dayTimeRecordRepository.Update(dayTimeRecord);
            ComputeSummary(dayTimeRecord);
        }

        public void Delete(int id)
        {
            var dayTimeRecord = GetById(id);
            if (dayTimeRecord != null)
            {
                _payrollSummaryService.ResetHours(dayTimeRecord.EmployeeId, dayTimeRecord.PayrollDateId);
                _dayTimeRecordRepository.Delete(dayTimeRecord);
            }                           
        }

        public bool Save()
        {
            string message;           
            _dayTimeRecordRepository.Save(out message);
            _payrollSummaryService.Save();
            return message == "Saved";
        }

        void ComputeSummary(DayTimeRecord dayTimeRecord)
        {
            var empPayrollSummary = _payrollSummaryService.GetEmployeePayrollSummary(dayTimeRecord.EmployeeId, dayTimeRecord.PayrollDateId);
            bool IsAdd = false;
            if (empPayrollSummary == null)
            {
                IsAdd = true;
                empPayrollSummary = new PayrollSummary { EmployeeId = dayTimeRecord.EmployeeId, PayRollId = dayTimeRecord.PayrollDateId };
            }

            //Regular Hours
            empPayrollSummary.RegularHours = dayTimeRecord.RegularTimeHours;
            empPayrollSummary.LegalHours = dayTimeRecord.LegalHolidayTimeHours;
            empPayrollSummary.SpecialHours = dayTimeRecord.SpecialHolidayTimeHours;
            //OverTime
            empPayrollSummary.OverTime = dayTimeRecord.RegularOverTimeHours;
            empPayrollSummary.OverTimeLegal = dayTimeRecord.LegalOverTimeHours;
            empPayrollSummary.OverTimeSpecial = dayTimeRecord.SpecialOverTimeHours;
            //NightDifferential
            empPayrollSummary.NightDiff = dayTimeRecord.RegularNightDiffTimeHours;
            empPayrollSummary.NightDiffSpecial = dayTimeRecord.SpecialNightDiffTimeHours;
            empPayrollSummary.NightDiffLegal = dayTimeRecord.LegalNightDiffTimeHours;
            
            
            if (IsAdd)
                _payrollSummaryService.Add(empPayrollSummary);
            else
                _payrollSummaryService.Update(empPayrollSummary);            
        }
    }
}
